import {config} from '../../../../config/env-configs'
import CryptoJS  from 'crypto-js'
import dayjs from 'dayjs'

/*
    WS用于Vue.mixin,混入Vue后会自动创建一个websocket实例this.ws,
    该实例会在Vue组件触发deactived和beforeDestroy事件时自动关闭,
    当wsOptions发生变化时会重新创建ws实例

    @param {Object} wsOptions{url: websocket地址, maxReconnectCount: 最大重连次数}
    @author liming
    @date 2020/6/22

    Example:
        import { WS } from "@/library/js/ws"
        export default {
            mixins: [WS],
            method:{
                test(){
                    this.ws.onmessage = ( message ) =>{
                        console.log(message)
                    }
                    let msg ={
                        name: 'xxx',
                        age: 18
                    }

                    this.ws.send( JSON.stringify(msg) )
                }
            }
        }
*/
export  default {
    data(){
        let rawStr = dayjs().format('YYYY-MM-DD HH:mm:ss');
        let wordArray = CryptoJS.enc.Utf8.parse(rawStr);
        let base64 = CryptoJS.enc.Base64.stringify(wordArray);
        let url = (/^ws/.test(config.video.ws.url) ?  config.video.ws.url : 'ws://' + window.location.host  + config.video.ws.url) + '?token=' + base64
        return {
            wsOptions:{
                url: url,
                maxReconnectCount: config.video.ws.maxReconnectCount,              
            },
            readyState: null,
        }
    },
    methods:{
        createWS(){
            if(this.readyState === WebSocket.OPEN || this.readyState === WebSocket.CONNECTING) return;
            let ws = new WebSocket(this.wsOptions.url)
            this.ws = ws;
            this.ws.onclose = this.wsOnClose;
            this.ws.onerror = this.wsOnError;
            this.ws.onmessage = this.wsOnMessage;
            this.ws.onopen = this.wsOnOpen;
            this.readyState = this.ws.readyState;
            this.keepAlive();
            return ws;
        },
        keepAlive(){
            this.wsKeepAliveTimer = setInterval(()=>{
                try{
                    this.ws.send(JSON.stringify({'keep-alive': true}))
                }
                catch{

                }
            },1000*10)
        },
        reconnect(){
            let reconnectCount = 0;
            let connect = ()=>{
                reconnectCount +=1;
                setTimeout(()=>{
                    this.createWS();
                }, reconnectCount * 1500)
                if( reconnectCount >=this.wsOptions.maxReconnectCount ) {
                    reconnectCount = null;
                    return;
                }
                connect();
            }
            connect();
        },
        wsClose(){
            if(this.ws && this.ws.close){
                this.ws.close();
                clearInterval(this.wsKeepAliveTimer)
            }
        },
        wsOnMessage(message){
            console.log(message)
        },
        wsOnError(event){
          console.log('webSocket Error: \n', event)
            
        },
        wsOnClose(){
            console.log('webSocket closed')
            this.readyState = this.ws.readyState;
            this.ws = null;
        },
    
        wsOnOpen(){
            console.log('webSocket opened')
            this.readyState = this.ws.readyState;
        },
    
    },
    watch:{
        wsOptions:{
            immediate: true,
            handler(){
                if(this.ws){
                    this.ws.close();
                    this.ws.onclose = ()=> this.reconnect();
        
                }else{
                  this.reconnect();
                }
            }
        }
    },
    deactived(){
        this.wsClose();
    },
    beforeDestroy(){
        this.wsClose();
    }
}